package org.nanotek.spring.batch.reader;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nanotek.Base;
import org.nanotek.base.PageItemBase;
import org.nanotek.base.ResultListBase;
import org.nanotek.hibernate.dao.DAO;
import org.nanotek.jobs.GenericReader;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ItemStream;
import org.springframework.batch.item.ItemStreamException;
import org.springframework.batch.item.NonTransientResourceException;
import org.springframework.batch.item.ParseException;
import org.springframework.batch.item.UnexpectedInputException;

//import com.ibatis.common.logging.LogFactory;
//import org.apache.log4j.Logger;

public class DAORecordReader<T extends Base<?>> extends GenericReader implements ItemStream{

	private  Log log = LogFactory.getLog(DAORecordReader.class);
	private DAO<T> dao;
	private ExecutionContext executionContext; 
	
	public DAORecordReader() 
	{}
	
	public DAORecordReader(DAO<T> dao) {
		super();
		this.dao = dao;
	}

	@Override
	public Base<?> read() throws Exception, UnexpectedInputException,
			ParseException, NonTransientResourceException {
		ResultListBase resultList = null;
		log.debug("Record Reader read");
		PageItemBase<?> pageItem = (PageItemBase<?>) executionContext.get(PageItemBase.class.getName());
		if (pageItem == null) { 
			pageItem = new PageItemBase<Long>(System.nanoTime());
			pageItem.setMaxRecords(20);
			pageItem.setStartRecord(0);
		}
		List<T> results = dao.listRecords(pageItem.getStartRecord(), pageItem.getMaxRecords());
		if (results.size()>0) { 
			pageItem.setStartRecord(results.size());
			executionContext.put(PageItemBase.class.getName(), pageItem);
			ArrayList<Base<?>> detachedResults = new ArrayList<Base<?>>();
			detachedResults.addAll(results);
			resultList = new ResultListBase(detachedResults);
		}
		log.debug("End Read");
		return resultList;
	}

	public DAO<T> getDao() {
		return dao;
	}

	public void setDao(DAO<T> dao) {
		this.dao = dao;
	}

	@Override
	public void open(ExecutionContext executionContext)
			throws ItemStreamException {
		this.executionContext = executionContext;
	}

	@Override
	public void update(ExecutionContext executionContext)
			throws ItemStreamException {
	}

	@Override
	public void close() throws ItemStreamException {
		this.executionContext = null;
	}
}
